<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
 */

namespace App\Controller;

use App\Helpers\Helper;
use App\Helpers\ImUtil;
use App\Helpers\RedisUtil;
use App\Model\UserMsgLog;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Swoole\Http\Request;
use Swoole\Server;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server as WebSocketServer;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\Redis\Redis;

class WebSocketController extends Controller implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
    /**
     * 发送消息
     * @param WebSocketServer $server
     * @param Frame $frame
     */
    public function onMessage($server, Frame $frame): void
    {
        //心跳刷新缓存
        $redis = RedisUtil::getRedis();
        //获取所有的客户端id
        $fdList = $redis->sMembers(RedisUtil::WS_CLIENT_FD_KEY);
        //如果当前客户端在客户端集合中,就刷新
        if (in_array($frame->fd, $fdList)) {
            $redis->sAdd(RedisUtil::WS_CLIENT_FD_KEY, $frame->fd);
            $redis->expire(RedisUtil::WS_CLIENT_FD_KEY, 7200);
        }
        $message = json_decode($frame->data, true);
        $result = $this->receiveMessage($message);

        if (!$result) return;
        $key = Helper::getListKey([$message['from_account'], $message['to_account']]);
        $msg['type'] = 'send_callback';
        $msg['key'] = $key;
        $msg['content'] = [
            // 'send' => $message['send'],
            'detail' =>  [
                'MsgType' => ImUtil::RONG_TEXT_TYPE,
                'MsgContent' => ['Text' => $message['message']]
            ],
            'msg_time' => date('Y-m-d H:i:s'),
            'from_userid' => $message['from_userid'],
            'to_userid' => $message['to_userid']
        ];
        $server->push($frame->fd, json_encode($msg));
    }

    protected function receiveMessage($msgObj = [])
    {
        if (!isset($msgObj['msg_type'])) return false;
        $msgType = ImUtil::RONG_TEXT_TYPE;
        log_info(__CLASS__ . "==receiveMessage=={$msgObj['message']}");
        switch ($msgObj['msg_type']) {
            case 'text':
                //文字消息
                if (isset($msgObj['from_account'])) {
                    $ret = ImUtil::sendTextMsg($msgObj['to_account'], $msgObj['message'], $msgObj['from_account']);
                    //\Log::info("SendMsg==" . json_encode($msgObj) . "==" . json_encode($ret));
                }
                break;
            case 'image':
                $image = explode(',', $msgObj['message']);
                $image = $image[1];
                // $img = F('test.png');
                // file_put_contents($img, base64_decode($image));
                // $ret = ImUtil::sendImageMsg($msgObj['to_account'], $img, $msgObj['from_account']);
                $msgType = 'JT:USER_IMAGE';
                break;
        }
        //存入库
        $info = [
            'from_account' => $msgObj['from_account'],
            'to_account' => $msgObj['to_account'],
            'msg_detail' => $this->buildChatDetail($msgObj, $msgType),
            'from_userid' => $msgObj['from_userid'],
            'to_userid' => $msgObj['to_userid'],
            'official' => 1,
            'msg_type' => $msgType
        ];
        $ret = UserMsgLog::create($info);
        return true;
    }

    /**
     * 构造消息体
     */
    function buildChatDetail($msgObj, $msgType)
    {
        $time = microtime(true) * 1000;
        if ($msgType == 'RC:TxtMsg') {
            return json_encode([
                "channelType" => "PERSON",
                "fromUserId" => $msgObj['from_account'],
                "toUserId" => $msgObj['to_account'],
                "msgTimestamp" => $time,
                "timestamp" => $time,
                "objectName" => $msgType,
                "content" => [
                    "content" => $msgObj['message'],
                    "extra" => "",
                    "isBurnAfterRead" => false,
                    "burnDuration" => 0
                ],
                "sensitiveType" => "0",
                "source" => "Web",
                "msgUID" => "",
                "signTimestamp" => $time,
                "nonce" => "",
                "signature" => "",
                "appKey" => "pgyu6atqp5mju"
            ]);
        }
    }

    /**
     * 客户端失去链接
     * @param Server $server
     * @param int $fd
     * @param int $reactorId
     */
    public function onClose($server, int $fd, int $reactorId): void
    {
        //删掉客户端id
        // $redis = $this->container->get(Redis::class);
        $redis = RedisUtil::getRedis();
        //移除集合中指定的value
        $redis->sRem(RedisUtil::WS_CLIENT_FD_KEY, $fd);
        var_dump('closed');
    }

    /**
     * 客户端链接
     * @param WebSocketServer $server
     * @param Request $request
     */
    public function onOpen($server, Request $request): void
    {
        //保存客户端id
        // $redis = $this->container->get(Redis::class);
        $redis = RedisUtil::getRedis();
        $res1 = $redis->sAdd(RedisUtil::WS_CLIENT_FD_KEY, $request->fd);
        var_dump($res1);

        $res = $redis->expire(RedisUtil::WS_CLIENT_FD_KEY, 7200);
        var_dump($res);

        // $server->push($request->fd, 'Opened');
    }
}
